package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @author tang
 * @data 2021/9/8
 * @apiNode
 */
@Service
@PropertySource("classpath:/image.properties")
public class FileServiceImpl implements FileService{
    @Value("${image.localDir}")
    private String localDir;
    @Value("${image.preUrl}")
    String preUrl;

    @Override
    public ImageVO upload(MultipartFile file){
        /**
         * 完成校验:
         *      1.校验是否为图片
         *      2.判断是否满足图片的固有属性  高度/宽度
         *      3.为了提高查询效率,要求分目录存储
         *          3.1 按照后缀名分配  jpg,png,gif  效率提升不能满足要求
         *          3.2 按照日期分  yyyy/mm/dd/hh  可以
         *          3.3 商品分类  出现分配不均
         *          3.4 根据名称hash 之后截串
         *              弊端:hash码可能出现分布不均的现象
         *      4. 防止文件重名 使用uuid代替文件名称
         */

        //1.获取文件名称
        String filename = file.getOriginalFilename();
        //由于Windows系统不区分大小写,所以将字母全部转化为小写
        filename = filename.toLowerCase();
        if (!filename.matches("^.+\\.(jpg|png|gif)$")){
            //如果不是图片则返回null
            return null;
        }
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());  //获取文件属性
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0){
                return null;
            }
            //根据时间实现目录的创建  yyyy/mm/dd
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());  //获取日期
            String localDirPath = localDir + dateDir;  //获取文件目录
            File dirFile = new File(localDirPath);  //创建文件对象
            if (!dirFile.exists()){   //判断是否存在
                dirFile.mkdirs();  //不存在则创建
            }
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");  //获取uuid作为文件名
            String fileType = filename.substring(filename.lastIndexOf("."));  //获取文件后缀
            String newFileName = uuid + fileType;  //文件全名

            String realFilePath = localDirPath + newFileName;  //文件绝对路径
            file.transferTo(new File(realFilePath));  //映射到本地磁盘

            String virTualPath = dateDir + newFileName;  //文件虚拟路径

            String url = preUrl + virTualPath;
            System.out.println("aa:"+realFilePath);
            System.out.println("aaa:"+url);
            ImageVO imageVO = new ImageVO();  //创建imageVO对象
            imageVO.setVirtualPath(virTualPath).setFileName(newFileName).setUrlPath(url);  //封装ImageVO数据
            return imageVO;  //返回imageVO数据
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 思路:
     *      1.根据虚拟地址拼接磁盘地址
     *      2.判断文件是否存在
     *      3.实现文件删除
     * @param virtualPath
     */
    @Override
    public void deleteFile(String virtualPath) {
        String path = localDir + virtualPath;   //生成本地磁盘地址
        File file = new File(path);
        if (file.exists()){
            file.delete();
        }
    }
}
